home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
ETO Development Tools 4
/
ETO Development Tools 4.iso
/
Tools - Objects
/
MacApp
/
MacApp 3.0a2
/
Libraries
/
UGeometry.cp
< prev
next >
Wrap
Text File
|
1991-05-01
|
17KB
|
671 lines
#ifndef __STDIO__
#include <StdIO.h>
#endif
#ifndef __UGEOMETRY__
#include <UGeometry.h>
#endif
#pragma segment Main
//========================================================================================
// VPoint method definitions
//========================================================================================
//----------------------------------------------------------------------------------------
// Conversion operator, for converting VPoint to a textual representation of a
// VPoint. "VPoint(v,h)". Formats VPoint in a static character string and returns
// a pointer to that static character string.
//----------------------------------------------------------------------------------------
VPoint::operator char*() const
{
static char textPoint[40];
sprintf (textPoint, "VPoint(%d, %d)", v, h);
return textPoint;
}
//----------------------------------------------------------------------------------------
// Conversion operator for converting a VPoint to a Point. Note that a newly
// allocated Point is returned. We are not just viewing a VPoint as a Point.
//----------------------------------------------------------------------------------------
VPoint::operator Point() const
{
Point pt;
pt.v = (short) v;
pt.h = (short) h;
return pt;
}
//----------------------------------------------------------------------------------------
// Selector operators for VPoint. Selects one of the two coordinates depending
// on the value of the sel parameter.
//----------------------------------------------------------------------------------------
VCoordinate& VPoint::operator[](VHSelect sel)
{
if (sel == vSel)
return v;
else
return h;
}
const VCoordinate& VPoint::operator[](VHSelect sel) const
{
if (sel == vSel)
return v;
else
return h;
}
//----------------------------------------------------------------------------------------
// Arithmatic operators for VPoint. Addition and subtraction are all that make
// any sense. Both the Add and AddTo forms are defined.
//----------------------------------------------------------------------------------------
VPoint VPoint::operator+(const VPoint& pt) const
{
VPoint returnPt;
returnPt.v = v + pt.v;
returnPt.h = h + pt.h;
return returnPt;
}
VPoint VPoint::operator-(const VPoint& pt) const
{
VPoint returnPt;
returnPt.v = v - pt.v;
returnPt.h = h - pt.h;
return returnPt;
}
VPoint VPoint::operator-() const
{
VPoint pt;
pt.v = -v;
pt.h = -h;
return pt;
}
VPoint& VPoint::operator+=(const VPoint& pt)
{
v += pt.v;
h += pt.h;
return *this;
}
VPoint& VPoint::operator-=(const VPoint& pt)
{
v -= pt.v;
h -= pt.h;
return *this;
}
//----------------------------------------------------------------------------------------
// Relational operators for VPoint. These are defined by applying the operator in
// question to both coordinates. The condition must hold for both to hold for the
// VPoints the corresponding VPoints.
//----------------------------------------------------------------------------------------
Boolean VPoint::operator!=(const VPoint& pt) const
{
return v != pt.v || h != pt.h;
}
Boolean VPoint::operator==(const VPoint& pt) const
{
return v == pt.v && h == pt.h;
}
Boolean VPoint::operator>(const VPoint& pt) const
{
return v > pt.v && h > pt.h;
}
Boolean VPoint::operator<(const VPoint& pt) const
{
return v < pt.v && h < pt.h;
}
Boolean VPoint::operator>=(const VPoint& pt) const
{
return v >= pt.v && h >= pt.h;
}
Boolean VPoint::operator<=(const VPoint& pt) const
{
return v <= pt.v && h <= pt.h;
}
//----------------------------------------------------------------------------------------
// Some useful methods to send to VPoints.
//----------------------------------------------------------------------------------------
void VPoint::ConstrainTo(const VRect& rt)
{
// If this point is not inside 'rt' then move it to the nearest edge.
if (v < rt.top)
v = rt.top;
if (v >= rt.bottom)
v = rt.bottom - 1;
if (h < rt.left)
h = rt.left;
if (h >= rt.right)
h = rt.right - 1;
}
//========================================================================================
// VRect method definitions
//========================================================================================
//----------------------------------------------------------------------------------------
// Conversion operator, for converting VRect to a textual representation of a VRect.
// "VRect(top,left,bottom,right)". Formats VRect in a static character string and returns
// a pointer to that static character string.
//----------------------------------------------------------------------------------------
VRect::operator char*() const
{
static char textPoint[80];
sprintf (textPoint, "VRect(%d, %d, %d, %d)", top, left, bottom, right);
return textPoint;
}
//----------------------------------------------------------------------------------------
// Conversion operator for converting a VRect to a Rect. Note that a newly allocated Rect
// is returned. We are not just viewing a VRect as a Rect. Also a constructor for
// constructing a VRect from a Rect.
//----------------------------------------------------------------------------------------
VRect::operator Rect() const
{
Rect pt;
pt.top = (short) top;
pt.left = (short) left;
pt.bottom = (short) bottom;
pt.right = (short) right;
return pt;
}
VRect::VRect(const Rect& rt)
{
top = rt.top;
left = rt.left;
bottom = rt.bottom;
right = rt.right;
}
//----------------------------------------------------------------------------------------
// Selector operators for VPoint. Selects one of the two coordinates depending on the
// value of the sel parameter.
//----------------------------------------------------------------------------------------
VPoint& VRect::operator[](PointSelector sel)
{
if (sel == topLeft)
return *((VPoint *) &top);
else
return *((VPoint *) &bottom);
}
const VPoint& VRect::operator[](PointSelector sel) const
{
if (sel == topLeft)
return *((VPoint *) &top);
else
return *((VPoint *) &bottom);
}
//----------------------------------------------------------------------------------------
// Operators for adding and subtracting one VRect from to/ from another. Both the Add and
// AddTo form of operators are defined.
//----------------------------------------------------------------------------------------
VRect VRect::operator+(const VRect& rt) const
{
VRect returnRect;
returnRect.top = top + rt.top;
returnRect.left = left + rt.left;
returnRect.bottom = bottom + rt.bottom;
returnRect.right = right + rt.right;
return returnRect;
}
VRect VRect::operator-(const VRect& rt) const
{
VRect returnRect;
returnRect.top = top - rt.top;
returnRect.left = left - rt.left;
returnRect.bottom = bottom - rt.bottom;
returnRect.right = right - rt.right;
return returnRect;
}
VRect& VRect::operator+=(const VRect& rt)
{
top += rt.top;
left+= rt.left;
bottom += rt.bottom;
right += rt.right;
return *this;
}
VRect& VRect::operator-=(const VRect& rt)
{
top -= rt.top;
left-= rt.left;
bottom-= rt.bottom;
right-= rt.right;
return *this;
}
//----------------------------------------------------------------------------------------
// Operators for adding and subtracting a VPoint to/ from a VRect. A VPoint is added to a
// VRect by adding the VPoint to both the top-left and bottom-right VPoints that define
// the VRect. Both the Add and AddTo operators are defined. Very convenient for
// translating VRects. These take a point and since VPoint has a constructor that takes
// two VCoordinates the VRect windowRect can be translated 100 pixels in the positive y
// direction by the statement:
//
// windowRect = windowRect + VPoint (0, 100); or
// windowRect += VPoint (0, 100);
//----------------------------------------------------------------------------------------
VRect VRect::operator+(const VPoint& pt) const
{
VRect returnRect;
returnRect.top = top + pt.v;
returnRect.left = left + pt.h;
returnRect.bottom = bottom + pt.v;
returnRect.right = right + pt.h;
return returnRect;
}
VRect VRect::operator-(const VPoint& pt) const
{
VRect returnRect;
returnRect.top = top - pt.v;
returnRect.left = left - pt.h;
returnRect.bottom = bottom - pt.v;
returnRect.right = right - pt.h;
return returnRect;
}
VRect VRect::operator-() const
{
VRect rt;
rt.top = -top;
rt.left = -left;
rt.bottom = -bottom;
rt.right = -right;
return rt;
}
VRect& VRect::operator+=(const VPoint& pt)
{
top += pt.v;
left+= pt.h;
bottom+= pt.v;
right+= pt.h;
return *this;
}
VRect& VRect::operator-=(const VPoint& pt)
{
top -= pt.v;
left -= pt.h;
bottom -= pt.v;
right -= pt.h;
return *this;
}
//----------------------------------------------------------------------------------------
// Inset a VRect using the coordinates in VPoint for the inset delta
//----------------------------------------------------------------------------------------
VRect& VRect::Inset(const VPoint& delta)
{
top += delta.v;
left += delta.h;
bottom -= delta.v;
right -= delta.h;
return *this;
}
//----------------------------------------------------------------------------------------
// Equality operators, other relational operator could be defined such as <. But their
// meaning is ambiguous and probably better implemented as methods. For example, aRect <
// bRect could return true if aRect was inside of bRect, or could return true if the area
// of aRect was less than the area of bRect.
//----------------------------------------------------------------------------------------
Boolean VRect::operator==(const VRect& rt) const
{
return
top == rt.top && left == rt.left &&
bottom == rt.bottom && right == rt.right;
}
Boolean VRect::operator!=(const VRect& rt) const
{
return
top != rt.top || left != rt.left ||
bottom != rt.bottom || right != rt.right;
}
//----------------------------------------------------------------------------------------
// Two simple area operators, the intersection & and the union ||. The definition of union
// here is to return a VRect that exactly encloses its operands.
//----------------------------------------------------------------------------------------
VRect VRect::operator &(const VRect& rt) const
{
VRect returnRect;
returnRect.top = Max(top, rt.top);
returnRect.left = Max(left, rt.left);
returnRect.bottom = Min(bottom, rt.bottom);
returnRect.right = Min(right, rt.right);
returnRect.Validate();
return returnRect;
}
VRect VRect::operator |(const VRect& rt) const
{
VRect returnRect;
returnRect.top = Min(top, rt.top);
returnRect.left = Min(left, rt.left);
returnRect.bottom = Max(bottom, rt.bottom);
returnRect.right = Max(right, rt.right);
return returnRect;
}
//----------------------------------------------------------------------------------------
// Returns true if a valid rectangle (left < right and top < bottom). If not a valid
// rectangle then return false and set all coordinates to 0.
//----------------------------------------------------------------------------------------
Boolean VRect::Valid() const
{
return left < right && top < bottom;
}
//----------------------------------------------------------------------------------------
// Sets all coordinates to 0 if the VRect is not a valid rectangle.
//----------------------------------------------------------------------------------------
Boolean VRect::Validate()
{
if (!this->Valid())
{
top = left = bottom = right = 0;
return false;
}
else
return true;
}
//----------------------------------------------------------------------------------------
// Empty returns true if the rectangle is empty.
//----------------------------------------------------------------------------------------
Boolean VRect::Empty() const
{
return right - left <= 0 || bottom - top <= 0;
}
//----------------------------------------------------------------------------------------
// Length returns the length of a VRect in a given dimension.
//----------------------------------------------------------------------------------------
VCoordinate VRect::Length(VHSelect sel) const
{
if (sel == vSel)
return bottom - top;
else
return right - left;
}
//----------------------------------------------------------------------------------------
// Size returns the size of a VRect as a VPoint.
//----------------------------------------------------------------------------------------
VPoint VRect::Size() const
{
return VPoint(bottom - top, right - left);
}
//----------------------------------------------------------------------------------------
// The Contains method takes either a VPoint or a VRect and returns true if the operand is
// inside of the VRect the method is applied to.
//----------------------------------------------------------------------------------------
Boolean VRect::Contains (const VPoint& pt) const
{
// Does the point 'pt' lie within the rectangle of 'this'?
return pt.v >= top && pt.v <= bottom && pt.h >= left && pt.h <= right;
}
Boolean VRect::Contains (const VRect& rt) const
{
// Does the rectangle 'rt' lie withing the rectagle of 'this'?
return Contains (rt[topLeft]) && Contains (rt[botRight]);
}
//----------------------------------------------------------------------------------------
// Max and Min are two private methods for comparing individual coordinates of VRects.
//----------------------------------------------------------------------------------------
VCoordinate VRect::Min (const VCoordinate a, const VCoordinate b) const
{
return a < b ? a : b;
}
VCoordinate VRect::Max (const VCoordinate a, const VCoordinate b) const
{
return a > b ? a : b;
}
//========================================================================================
// The following global routines maintain Pascal compatibility. They are basically
// wrappers that call back into the methods in VRect and VPoint. Interfaces for these
// routines are only provided in the Pascal headers. C++ programs should use the methods
// in VRect and VPoint to avoid the additional function call overhead.
//========================================================================================
//----------------------------------------------------------------------------------------
// The following routines make dealing with VPoint as arguments much easier. e.g. the
// Resize method used to take v,h coordinate pair, now it takes a VPoint. These routines
// allow one to do arithmetic on the arguments to Resize without creating a temporary
// VPoint.
//
// NOTE: No interface to these functions is defined for C++, since there is a bug in the C
// compiler when using Pascal calling conventions to return structs greater than 4 bytes.
//----------------------------------------------------------------------------------------
pascal VPoint CreateVPt(const VCoordinate v, const VCoordinate h)
{
return VPoint(v, h);
}
pascal VPoint VPtAddVPt(const VPoint& aPt, const VPoint& bPt)
{
return aPt + bPt;
}
pascal VPoint VPtSubVPt(const VPoint& aPt, const VPoint& bPt)
{
return aPt - bPt;
}
//----------------------------------------------------------------------------------------
// Wrappers for for object Pascal for some of the functions that are defined on the C++
// stack based classes Point, VPoint, Rect, VRect.
//----------------------------------------------------------------------------------------
pascal void PtToVPt(const Point thePt, VPoint& theVPt)
{
theVPt.h = thePt.h;
theVPt.v = thePt.v;
}
pascal Point VPtToPt(const VPoint& theVPt)
{
return theVPt;
}
pascal void RectToVRect(const Rect& theRect, VRect& theVRect)
{
theVRect.top = theRect.top;
theVRect.left = theRect.left;
theVRect.bottom = theRect.bottom;
theVRect.right = theRect.right;
}
pascal void VRectToRect(const VRect& theVRect, Rect& theRect)
{
theRect = theVRect;
}
pascal void AddVPt(const VPoint& srcVPt, VPoint& dstVPt)
{
dstVPt += srcVPt;
}
pascal void SubVPt(const VPoint& srcVPt, VPoint& dstVPt)
{
dstVPt -= srcVPt;
}
pascal void SetVPt(VPoint& vPt, VCoordinate h, VCoordinate v)
{
vPt.h = h;
vPt.v = v;
}
pascal Boolean EqualVPt(const VPoint& aVPt, const VPoint& bVPt)
{
return aVPt == bVPt;
}
pascal void SetVRect(VRect& vRt,
VCoordinate left, VCoordinate top,
VCoordinate right, VCoordinate bottom)
{
vRt.left = left;
vRt.top = top;
vRt.right = right;
vRt.bottom = bottom;
}
pascal void OffsetVRect(VRect& vRt, VCoordinate dh, VCoordinate dv)
{
vRt += VPoint(dv, dh);
}
pascal void InsetVRect(VRect& vRt, VCoordinate dh, VCoordinate dv)
{
vRt.Inset(VPoint(dv, dh));
}
pascal void Pt2VRect(const VPoint& theTopLeft, const VPoint& theBotRight, VRect& vRt)
{
vRt[topLeft] = theTopLeft;
vRt[botRight] = theBotRight;
}
pascal Boolean PtInVRect(const VPoint& vPt, const VRect& vRt)
{
return vRt.Contains(vPt);
}
pascal Boolean EmptyVRect(const VRect& vRt)
{
return vRt.Empty();
}
pascal Boolean EqualVRect(const VRect& aVRt, const VRect& bVRt)
{
return aVRt == bVRt;
}
pascal VCoordinate LengthVRect(const VRect& vRt, VHSelect whichDim)
{
return vRt.Length(whichDim);
}
pascal void PinVRect(const VRect& vRt, VPoint& vPt)
{
vPt.ConstrainTo(vRt);
}
pascal Boolean SectVRect(const VRect& src1, const VRect& src2, VRect& dst)
{
dst = src1 & src2;
return dst.Valid();
}
pascal void UnionVRect(const VRect& src1, const VRect& src2, VRect& dst)
{
dst = src1 | src2;
}